package com.klun.concTrueWar.ten.A_DeadLock_10_1;


import javax.naming.InsufficientResourcesException;
import java.math.BigDecimal;
import java.util.Random;

/**
 * 10-4 在典型条件下发生死锁的循环
 */
public class DemonstrateDeadLock {
    private static final int NUM_THREADS = 20;
    private static final int NUM_ACCOUNTS = 5;
    private static final int NUM_ITERATIONS = 1000000;
    private static final Object tieLock = new Object();

    public static void main (String[] args){
        final Random rnd = new Random();
        final Account[] accounts = new Account[NUM_ACCOUNTS];
        for (int i = 0; i < accounts.length; i++) {
            accounts[i] = new Account();
        }
        class TransferThread extends Thread{
            public void run(){
                for (int i = 0; i < NUM_ITERATIONS; i++) {
                    int fromAcct = rnd.nextInt(NUM_ACCOUNTS);
                    int toAcct = rnd.nextInt(NUM_ACCOUNTS);
                    DollarAmount amount =
                            new DollarAmount(rnd.nextInt(1000));
                    transferMoney(accounts[fromAcct],accounts[toAcct],amount);
                } 
            }
        }
        for (int i = 0; i < NUM_THREADS; i++) {
            new TransferThread().start();
        }
    }
    public static void transferMoney(final Account fromAcct
            ,final Account toAcct ,final DollarAmount amount){
        class Helper {
            public void transger() throws InsufficientResourcesException {
                if(fromAcct.getBalance().compareTo(amount) < 0){
                    throw new InsufficientResourcesException();
                }
                else {
                    fromAcct.debit(amount);
                    toAcct.credit(amount);
                }
            }
        }
    }
}
class Account {
    private DollarAmount balance;

    public DollarAmount getBalance() {
        return balance;
    }
    public void debit(DollarAmount amount){

    }
    public void credit(DollarAmount amount){

    }
    public void setBalance(DollarAmount balance) {
        this.balance = balance;
    }
}
class DollarAmount{

    private BigDecimal amount;

    public DollarAmount(int amount) {
        this.amount = new BigDecimal(amount);
    }

    public BigDecimal getAmount() {
        return amount;
    }

    public void setAmount(BigDecimal amount) {
        this.amount = amount;
    }

    public int compareTo(DollarAmount amount){
        return amount.getAmount().compareTo(this.amount);
    }
}